<template>
  <div class="goods-sku">
    <dl v-for="(v, i) in obj.specs" :key="i">
      <dt>{{ v.name }}</dt>
      <dd>
        <template v-for="(item, ii) in v.values" :key="ii">
          <!-- template 标签 -->
          <img
            :class="{ selected: item.selected, disabled: item.disabled }"
            :src="item.picture"
            alt=""
            v-if="item.picture"
            @click="changeFlag(v, item)"
          />

          <span
            @click="changeFlag(v, item)"
            :class="{ selected: item.selected, disabled: item.disabled }"
            v-else
            >{{ item.name }}{{ item.disabled }}</span
          >
        </template>
      </dd>
    </dl>
  </div>
</template>
<script>
import { ref } from "vue";
import getPowerSet from "@/vender/powerSet.js";
// 得到一个路径字典对象  这里封装的是 是否禁用商品规格
const spliter = "★";
// 根据skus数据得到路径字典对象
const getPathMap = (skus) => {
  const pathMap = {};
  skus.forEach((sku) => {
    // 1. 过滤出有库存有效的sku
    if (sku.inventory) {
      // 2. 得到sku属性值数组
      const specs = sku.specs.map((spec) => spec.valueName);
      // 3. 得到sku属性值数组的子集
      const powerSet = getPowerSet(specs);
      // 4. 设置给路径字典对象
      powerSet.forEach((set) => {
        const key = set.join(spliter);
        if (pathMap[key]) {
          // 已经有key往数组追加
          pathMap[key].push(sku.id);
        } else {
          // 没有key设置一个数组
          pathMap[key] = [sku.id];
        }
      });
    }
  });
  return pathMap;
};

// 得到当前选中规格集合
const getSelectedArr = (specs) => {
  const selectedArr = [];
  specs.forEach((spec) => {
    const selectedVal = spec.values.find((val) => val.selected);
    selectedArr.push(selectedVal ? selectedVal.name : undefined);
  });
  return selectedArr;
};

// 更新按钮的禁用状态   specs 是传入的每条规格数据， PathMap 是路径字典数据
const updateDisabledStatus = (specs, pathMap) => {
  specs.forEach((spec, i) => {
    const selectedArr = getSelectedArr(specs);
    spec.values.forEach((val) => {
      // 已经选中的按钮不用判断
      if (val.name === selectedArr[i]) return false;
      // 未选中的替换对应的值
      selectedArr[i] = val.name;
      // 过滤无效值得到key
      const key = selectedArr.filter((v) => v).join(spliter);
      // 设置禁用状态
      val.disabled = !pathMap[key];
    });
  });
};

// 初始化选中状态
const initSelectedStatus = (goods, skuId) => {
  // 先找它id 匹配传过 来的 id 那条数据
  const sku = goods.skus.find((sku) => sku.id === skuId);
  // 判断是否有数据
  if (sku) {
    // 循环找到的那条数据 遍历到那条数据
    goods.specs.forEach((spec, i) => {
      // 取出  specs 每一条 小数据 的 valueName
      const value = sku.specs[i].valueName;
      // 然后循环 遍历 每一个数据
      spec.values.forEach((val) => {
        // 如果 values 每条数据 里面的name  === value 就把 selected 变为true
        val.selected = val.name === value;
      });
    });
  }
};

export default {
  name: "GoodsSku",
  props: {
    obj: {
      type: Object,
    },
    skuId: {
      type: String,
      default: "",
    },
  },
  setup(props, { emit }) {
    // 把 props 传入 getPathMap 这个函数
    const pathMap = getPathMap(props.obj.skus);
    console.log(pathMap);
    // 组件初始化的时候更新一下按钮的禁用状态 传入每条规格 和  路径字典
    updateDisabledStatus(props.obj.specs, pathMap);
    // 初始化默认选中状态
    initSelectedStatus(props.obj, props.skuId);
    // 作为选中的状态
    let flag = ref(0);
    // 规格商品的 class 类激活
    function changeFlag(v, item) {
      // 当按钮禁用 阻止程序运行
      if (item.disabled) return;
      if (item.selected) {
        // 判断激活类 如果 true = false
        item.selected = false;
      } else {
        // 循环父数据里面子数据的 selected 给他变为false
        v.values.forEach((item) => {
          item.selected = false;
        });
        // 如果为false 就等于 true
        item.selected = true;
      }
      // 点击更新 更新 按钮的禁用状态
      updateDisabledStatus(props.obj.specs, pathMap);

      // 有数据就过滤出来 没有数据就 不过滤
      const validSelectValues = getSelectedArr(props.obj.specs).filter(
        (v) => v
      );
      // 完整可以拿到这组数据发个父组件
      if (validSelectValues.length == props.obj.specs.length) {
        console.log(validSelectValues);
        // 拿到  路径字典 pathMap 选中这组数据的id
        const skuId = pathMap[validSelectValues.join(spliter)];
        // 从 props.obj.skus 里面找到 选中的 路径字典 id
        const skus = props.obj.skus.find((skusItem) => skusItem.id == skuId[0]);
        console.log(skus);
        emit("changeSelect", {
          skuId: skus.id,
          price: skus.price ,
          oldPrice: skus.oldPrice ,
          inventory: skus.inventory,
          // 把选中的字符串给拼接一下
          specsText: skus.specs
            .reduce((p, n) => `${p} ${n.name}: ${n.valueName}`, "")
            .replace(" ", ""),
        });
      } else {
        // 不完整 通知给父组件 一个空对象   这里是应为 让 父组件判断规格是否完整 不完整 就不能加入购物车了
        emit("changeSelect", {});
        console.log("不完整");
      }
    }

    return { flag, changeFlag };
  },
};
</script>
<style scoped lang="scss">
@mixin sku-state-mixin {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
}
.selected {
  border: 1px solid $xtxColor !important;
}
.disabled {
  opacity: 0.6 !important;
  border-style: dashed !important;
  cursor: no-drop !important;
  user-select: none;
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        @include sku-state-mixin;
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        @include sku-state-mixin;
      }
    }
  }
}
</style>
